/*
PearReview - The peer review assistant.
Copyright (C) 2009  Dimitrij Pankratz, Anton Musichin
http://www.pearreview.com, info@pearreview.com

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

package com.pearreview.reviewerplugin;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Formatter;
import java.util.LinkedList;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JSplitPane;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import com.pearreview.application.FileHistory;
import com.pearreview.application.MenuBarAdapter;
import com.pearreview.application.Messages;
import com.pearreview.application.Plugin;
import com.pearreview.application.PluginAdapter;
import com.pearreview.application.SaveData;
import com.pearreview.application.FileHistory.ChangeEvent;
import com.pearreview.reviewerplugin.io.ReportReader;
import com.pearreview.reviewerplugin.io.ReportWriter;
import com.pearreview.reviewerplugin.io.XMLReportReader;
import com.pearreview.reviewerplugin.io.XMLReportWriter;
import com.pearreview.ui.FileMenuItem;
import com.pearreview.ui.ToolBarSeparator;
import com.pearreview.ui.PearToolBar;
import com.pearreview.ui.StepTabs;
import com.pearreview.ui.ToolBarButtonUI;
import com.pearreview.ui.clock.ScribeClock;

public class ReviewerPlugin implements Plugin {
	
	private static final long serialVersionUID = 8697451089966176596L;
	
	public static final String FILE_HISTORY_TYPE = "report-xml";
	
	private PluginAdapter pluginAdapter;
	
	/**
	 * 0: normal start (default)<br>
	 * 1: creates new review on start <br>
	 * 2: opens review file on start
	 * 3: load save data
	 */
	private short startMode = 0;
	/**
	 * file to open on start
	 */
	private File fileToOpen;
	/**
	 * save data to load at start
	 */
	private SaveData saveData;
	
	/**
	 * Current report
	 */
	private Report report;
	/**
	 * Current report file, if available
	 */
	private File reportFile;
	/**
	 * Starts the clock if findingsPanel gets selected and this flag 
	 * is <code>true</code>, otherwise does nothing.
	 */
	private boolean startClockByNextFindingsPanelVisit = false;
	
	private JToolBar toolBar;
	private JSplitPane splitPane;
	private StepTabs stepTabs;
	private String[] steps = {
			getLocalizedString("tabs.start"),
			getLocalizedString("tabs.information"),
			getLocalizedString("tabs.findings"),
			getLocalizedString("tabs.final")};
	private ReviewerPanel[] views;
	private int lastViewIndex = -1;
	
	/* step panels */
	private StartPanel startPanel;
	private InformationPanel informationPanel;
	private FindingsPanel findingsPanel;
	private FinalPanel finalPanel;
	private ScribeClock clock;
	
	/* actions */
	private Action nextViewAction = new NextViewAction();
	private Action previousViewAction = new PreviousViewAction();
	private Action firstViewAction = new FirstViewAction();
	private Action newReportAction = new NewReportAction();
	private Action openReportAction = new OpenReportAction();
	private Action openReportFileAction = new OpenReportFileAction();
	private Action saveReportAction = new SaveReportAction();
	private Action saveAsReviewAction = new SaveAsReportAction();
	private Action navigateToHomeAction = new NavigateToHomeAction();
	private Action newTabActionAction = new NewTabAction();
	private Action fullScreenAction = new FullScreenAction();
	
	/**
	 * Returns default report file.
	 * @return default report file
	 */
	public static File getDefaultSaveAsFile() {
		return new File("report_" + 
				new SimpleDateFormat("dd.MM.yyyy").format(new Date()));
	}
	
	@Override
	public boolean close() {
		if(!isStartMode()) {
			String message = getLocalizedString("confirm.close");
			Formatter formatter = new Formatter();
			if(reportFile == null) {
				message = formatter.format(message, 
						getLocalizedString("start.new_file")).toString();
			}
			else {
				message = formatter.format(message, 
						reportFile.getName()).toString();
			}
			
			int option = JOptionPane.showConfirmDialog(getComponent(), 
					message, 
					getLocalizedString("confirm.close.title"), 
					JOptionPane.YES_NO_CANCEL_OPTION);
			
			switch(option) {
			case JOptionPane.CANCEL_OPTION:
				return false;
				
			case JOptionPane.NO_OPTION:
				return true;
				
			case JOptionPane.YES_OPTION:
				return saveReport();
			}
		}
		
		return true;
	}
	
	@Override
	public SaveData getSaveData() {
		ReviewerPluginSaveData rpsd = new ReviewerPluginSaveData();
		
		rpsd.putValue(ReviewerPluginSaveData.REPORT_KEY, 
				getReport());
		rpsd.putValue(ReviewerPluginSaveData.REPORT_FILE_KEY, 
				reportFile);
		rpsd.putValue(ReviewerPluginSaveData.VIEW_KEY, 
				stepTabs.getSelectedIndex());
		rpsd.putValue(ReviewerPluginSaveData.VIEW_STATES_KEY, 
				stepTabs.getStates());
		
		rpsd.putValue(ReviewerPluginSaveData.CLOCK_START_KEY, 
				startClockByNextFindingsPanelVisit);
		
		if(finalPanel != null) {
			rpsd.putValue(ReviewerPluginSaveData.EXPORT_FILE_KEY, 
					finalPanel.getLastExportFile());
			rpsd.putValue(ReviewerPluginSaveData.EXPORT_IMAGES_KEY, 
					finalPanel.isPrintImagesSelected());
		}
		
		if(clock != null) {
			rpsd.putValue(ReviewerPluginSaveData.CLOCK_RUNNING_KEY, 
					clock.isRunning());
		}
		
		return rpsd;
	}
	
	@Override
	public String getTitle() {
		return getLocalizedString("title");
	}
	
	@Override
	public void loadSaveDataOnRun(SaveData data) {
		startMode = 3;
		fileToOpen = null;
		saveData = data;
	}
	
	public void newReportOnRun() {
		startMode = 1;
		fileToOpen = null;
		saveData = null;
	}
	
	public void openReportOnRun(File file) {
		startMode = 2;
		fileToOpen = file;
		saveData = null;
	}
	
	@Override
	public void run(PluginAdapter pa) {
		pluginAdapter = pa;
		
		initialize();
		
		getPluginAdapter().setComponent(getComponent());
		getPluginAdapter().setToolBar(getToolBar());
		getPluginAdapter().setTabIcon(getResourceIcon("reviewer-tab.png"));
		
		switch(startMode) {
		case 1:
			newReport();
			break;
		case 2:
			openReport(fileToOpen);
			break;
		case 3:
			loadSaveData(saveData);
			break;
		}
	}
	
	public PluginAdapter getPluginAdapter() {
		return pluginAdapter;
	}
	
	private void initialize() {
		startPanel = new StartPanel(getPluginAdapter(), newReportAction, 
				openReportAction, openReportFileAction);
		
		views = new ReviewerPanel[]{startPanel};
		
		stepTabs = new StepTabs(steps);
		stepTabs.setSelectedIndex(0);
		stepTabs.setMaxSelectionIndex(0);
		stepTabs.addListSelectionListener(new TabListener());
		
		splitPane = new JSplitPane();
		splitPane.setLeftComponent(stepTabs);
		splitPane.setRightComponent(startPanel);
		splitPane.setContinuousLayout(true);
		splitPane.setBackground(new Color(0xd6d6d6));
		splitPane.setOneTouchExpandable(true);
		splitPane.setBorder(null);
		
		initializeMenuBar();
		
		updateView();
	}
	
	private void initializeMenuBar() {
		final MenuBarAdapter mba = getPluginAdapter().getMenuBarAdapter();
		
		mba.addFileMenuItem(new JMenuItem(navigateToHomeAction));
		
		/* separator */
		mba.addFileMenuItem(null);
		
		/* new report */
		mba.addFileMenuItem(new JMenuItem(newReportAction));
		
		/* open report */
		mba.addFileMenuItem(new JMenuItem(openReportAction));
		
		/* save report */
		mba.addFileMenuItem(new JMenuItem(saveReportAction));
		
		/* save as report */
		mba.addFileMenuItem(new JMenuItem(saveAsReviewAction));
		
		/* file history */
		final FileHistory fh = getPluginAdapter().getFileHistory();
		fh.addChangeListener(new FileHistory.ChangeListener() {
			private static final long serialVersionUID = 8948507847266853282L;
			@Override
			public void typeChanged(ChangeEvent ce) {
				if(ReviewerPlugin.FILE_HISTORY_TYPE.equals(ce.getType())) {
					mba.setFileHistoryMenuItems(createFileHistoryItems(fh));
				}
			}
		});
		mba.setFileHistoryMenuItems(createFileHistoryItems(fh));
	}
	
	protected List<JMenuItem> createFileHistoryItems(FileHistory fh) {
		List<File> files = fh.getFiles(ReviewerPlugin.FILE_HISTORY_TYPE);
		List<JMenuItem> items = new LinkedList<JMenuItem>();
		
		ActionListener al = new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				FileMenuItem item = (FileMenuItem) e.getSource();
				openReport(item.getFile());
			}
		};
		
		int min = Math.min(9, files.size());
		for(int i = 0 ; i < min ; i++) {
			final File file = files.get(i);
			final JMenuItem item = new FileMenuItem(file, 0x31 + i);
			item.addActionListener(al);
			items.add(item);
		}
		
		return items;
	}
	
	public Component getComponent() {
		return splitPane;
	}
	
	public JToolBar getToolBar() {
		if(toolBar != null) {
			return toolBar;
		}
		
		//---- tool bar ----
		toolBar = new PearToolBar();
		
		toolBar.setFloatable(false);
		toolBar.setBackground(new Color(0xd6, 0xd6, 0xd6));
		
		toolBar.setBorder(BorderFactory.createMatteBorder(
				0, 0, 1, 0, new Color(0x828790)));
		
		//---- backBtn ----
		JButton backBtn = new JButton();
		backBtn.setAction(previousViewAction);
		Icon ico_prev = getResourceIcon("prev_toolbar_btn.png");
		Icon ico_prev_hover = getResourceIcon("prev_hover_toolbar_btn.png");
		backBtn.setIcon(ico_prev);
		backBtn.setUI(new ToolBarButtonUI(ico_prev_hover));
		backBtn.setToolTipText(
				Messages.getString("PearReview.toolbar.previous"));
		backBtn.setOpaque(false);
		
		//---- toStartBtn ----
		JButton toStartBtn = new JButton();
		toStartBtn.setAction(firstViewAction);
		Icon ico_home = getResourceIcon("home_toolbar_btn.png");
		Icon ico_home_hover = getResourceIcon("home_hover_toolbar_btn.png");
		toStartBtn.setIcon(ico_home);
		toStartBtn.setUI(new ToolBarButtonUI(ico_home_hover));
		toStartBtn.setToolTipText(
				Messages.getString("PearReview.toolbar.start"));
		toStartBtn.setOpaque(false);
		
		//---- forwardBtn ----
		JButton forwardBtn = new JButton();
		forwardBtn.setAction(nextViewAction);
		Icon ico_next = getResourceIcon("next_toolbar_btn.png");
		Icon ico_next_hover = getResourceIcon("next_hover_toolbar_btn.png");
		forwardBtn.setIcon(ico_next);
		forwardBtn.setUI(new ToolBarButtonUI(ico_next_hover));
		forwardBtn.setToolTipText(
				Messages.getString("PearReview.toolbar.next"));
		forwardBtn.setOpaque(false);
		
		//---- homeTabBtn ----
		JButton homeTabBtn = new JButton();
		homeTabBtn.setAction(navigateToHomeAction);
		Icon ico_homeTabBtn = getResourceIcon("tab-home.png");
		Icon ico_homeTabBtn_hover = getResourceIcon("tab-home_hover.png");
		homeTabBtn.setIcon(ico_homeTabBtn);
		homeTabBtn.setUI(new ToolBarButtonUI(ico_homeTabBtn_hover));
		homeTabBtn.setToolTipText(getLocalizedString("menu.home"));
		homeTabBtn.setOpaque(false);
		
		//---- saveBtn ----
		JButton saveBtn = new JButton();
		saveBtn.setAction(saveReportAction);
		Icon ico_saveBtn = getResourceIcon("save_btn.png");
		Icon ico_saveBtn_hover = getResourceIcon("save_hover_btn.png");
		saveBtn.setIcon(ico_saveBtn);
		saveBtn.setUI(new ToolBarButtonUI(ico_saveBtn_hover));
		saveBtn.setToolTipText(
				Messages.getString("PearReview.Reviewer.menu.save"));
		saveBtn.setOpaque(false);
		
		//---- newBtn ----
		JButton newBtn = new JButton();
		newBtn.setAction(newReportAction);
		Icon ico_newBtn = getResourceIcon("new_hover_btn.png");
		Icon ico_newBtn_hover = getResourceIcon("new_btn.png");
		newBtn.setIcon(ico_newBtn);
		newBtn.setUI(new ToolBarButtonUI(ico_newBtn_hover));
		newBtn.setToolTipText(
				Messages.getString("PearReview.Reviewer.menu.new"));
		newBtn.setOpaque(false);
		
		//---- newTabBtn ----
		JButton newTabBtn = new JButton();
		newTabBtn.setAction(newTabActionAction);
		Icon ico_newTabBtn = getResourceIcon("tab-new.png");
		Icon ico_newTabBtn_hover = getResourceIcon("tab-new_hover.png");
		newTabBtn.setIcon(ico_newTabBtn);
		newTabBtn.setUI(new ToolBarButtonUI(ico_newTabBtn_hover));
		newTabBtn.setToolTipText(
				Messages.getString("PearReview.menu.file.new_tab"));
		newTabBtn.setOpaque(false);
		
		//---- fullscreenBtn ----
		JButton fullscreenBtn = new JButton();
		fullscreenBtn.setAction(fullScreenAction);
		Icon ico_fullscreenBtn = getResourceIcon("fullscreen_hover.png");
		Icon ico_fullscreenBtn_hover = getResourceIcon("fullscreen.png");
		fullscreenBtn.setIcon(ico_fullscreenBtn);
		fullscreenBtn.setUI(new ToolBarButtonUI(ico_fullscreenBtn_hover));
		fullscreenBtn.setToolTipText(
				Messages.getString("PearReview.menu.view.fullscreen"));
		fullscreenBtn.setOpaque(false);
		
		toolBar.setPreferredSize(new Dimension(Short.MAX_VALUE, 36));
		
		toolBar.add(backBtn);
		toolBar.add(toStartBtn);
		toolBar.add(forwardBtn);
		
		toolBar.add(new ToolBarSeparator(55));
		
		toolBar.add(newBtn);
		toolBar.add(saveBtn);
		toolBar.add(homeTabBtn);
		toolBar.add(newTabBtn);
		toolBar.add(fullscreenBtn);
		
		return toolBar;
	}
	
	/**
	 * Returns a resource icon
	 * @param name name of icon
	 * @return
	 */
	private ImageIcon getResourceIcon(String name) {
		return new ImageIcon(getClass().getResource("images/" + name));
	}
	
	/**
	 * Returns localized string of this component
	 * @param key key of string to localize
	 * @return localized string of this component
	 */
	private static String getLocalizedString(String key) {
		return Messages.getString("PearReview.Reviewer." + key);
	}
	
	private void updateView() {
		if(lastViewIndex == stepTabs.getSelectedIndex())
			return;
		
		if(!isStartMode()) {
			stepTabs.setTabChecked(lastViewIndex);
		}
		
		int divederLoc;
		//set only first time and save then the position
		//after tab changing
		if (splitPane.getDividerLocation() == -1) {
			divederLoc = 180;
		} else {
			divederLoc = splitPane.getDividerLocation();
		}
		
		int index = stepTabs.getSelectedIndex();
		index = Math.max(index, 0);
		
		if(!isStartMode() && views[index] != findingsPanel) {
			finalPanel.setPreparationTime(clock.getPassedTime());
			clock.pauseTimer();
		} else if(!isStartMode() && views[index] == findingsPanel && 
				startClockByNextFindingsPanelVisit) {
			startClockByNextFindingsPanelVisit = false;
			clock.startTimer();
		}
		
		applyReport();
		
		lastViewIndex = index;
		
		splitPane.setRightComponent(views[index]);
		splitPane.setDividerLocation(divederLoc);
		
		updateActions();
	}
	
	public void applyReport() {
		for(ReviewerPanel panel: views) {
			panel.applyReport();
		}
	}
	
	private void updateActions() {
		int selected = stepTabs.getSelectedIndex();
		int max = Math.max(stepTabs.getMaxSelectionIndex(), views.length - 1);
		
		nextViewAction.setEnabled(selected < max);
		previousViewAction.setEnabled(selected != 0);
		firstViewAction.setEnabled(selected != 0);
	}
	
	public void setView(int index) {
		stepTabs.setSelectedIndex(index);
	}
	
	public int getSizeView() {
		return views.length;
	}
	
	public void setNextView() {
		stepTabs.setSelectedIndex(stepTabs.getSelectedIndex() + 1);
	}
	
	public void setPreviousView() {
		stepTabs.setSelectedIndex(stepTabs.getSelectedIndex() - 1);
	}
	
	public Report getReport() {
		applyReport();
		return report;
	}
	
	public boolean isStartMode() {
		return report == null;
	}
	
	/**
	 * loads save data
	 * @param sd save data to load
	 */
	public void loadSaveData(SaveData sd) {
		if(sd instanceof ReviewerPluginSaveData) {
			ReviewerPluginSaveData rpsd = (ReviewerPluginSaveData)sd;
			
			reportFile = (File) rpsd.getValue(
					ReviewerPluginSaveData.REPORT_FILE_KEY);
			Report report = (Report) rpsd.getValue(
					ReviewerPluginSaveData.REPORT_KEY);
			Integer view = (Integer) rpsd.getValue(
					ReviewerPluginSaveData.VIEW_KEY);
			Integer[] states = (Integer[]) rpsd.getValue(
					ReviewerPluginSaveData.VIEW_STATES_KEY);
			File lastExportFile = (File) rpsd.getValue(
					ReviewerPluginSaveData.EXPORT_FILE_KEY);
			Boolean printImages = (Boolean) rpsd.getValue(
					ReviewerPluginSaveData.EXPORT_IMAGES_KEY);
			Boolean clockRunning = (Boolean) rpsd.getValue(
					ReviewerPluginSaveData.CLOCK_RUNNING_KEY);
			Boolean clockStart = (Boolean) rpsd.getValue(
					ReviewerPluginSaveData.CLOCK_START_KEY);
			
			setReport(report);
			
			setView(view);
			stepTabs.setStates(states);
			if(reportFile != null && report != null) {
				getPluginAdapter().setTitle(reportFile.getName(), 
						reportFile.getAbsolutePath());
				getPluginAdapter().setFile(reportFile);
			} else if(report != null) {
				getPluginAdapter().setTitle(
						getLocalizedString("start.new_file"), 
						getLocalizedString("start.new_file"));
			}
			
			if(finalPanel != null) {
				if(lastExportFile != null) {
					finalPanel.setLastExportFile(lastExportFile);
				}
				if(printImages != null) {
					finalPanel.setPrintImagesSelected(printImages);
				}
			}
			
			if(clock != null && clockRunning != null) {
				if(clockRunning) {
					clock.startTimer();
				} else {
					clock.pauseTimer();
				}
			}
			
			if(clockStart != null) {
				startClockByNextFindingsPanelVisit = clockStart;
			}
		}
	}
	
	/**
	 * Save the review. if report was not saved before, 
	 * method <code>SaveAsReport</code> will be called
	 * 
	 * @return <code>true</code> if review was successful saved
	 */
	public boolean saveReport() {
		if(reportFile == null) {
			return saveAsReport();
		} else {
			return writeReport(reportFile);
		}
	}
	
	/**
	 * Show save under dialog, and save the current report to selected file
	 * by using method <code>writeReport</code>.
	 * @return <code>true</code> if review was saved, 
	 * otherwise <code>false</code>
	 */
	public boolean saveAsReport() {
		final JFileChooser saveDialog = new JFileChooser();
		saveDialog.setMultiSelectionEnabled(false);
		saveDialog.setAcceptAllFileFilterUsed(false);
		
		ReportFileFilter reportFilter = new ReportFileFilter();
		saveDialog.setFileFilter(reportFilter);
		
		saveDialog.setCurrentDirectory(reportFile);
		saveDialog.setSelectedFile(
				reportFile == null ? getDefaultSaveAsFile() : reportFile);
		
		getPluginAdapter().getSpringGlassPane().setFaded(true);
		int ret = saveDialog.showSaveDialog(getComponent());
		getPluginAdapter().getSpringGlassPane().setFaded(false);
			 
		if (JFileChooser.APPROVE_OPTION != ret)
			return false;
		
		File selectedFile = saveDialog.getSelectedFile();
		if(!reportFilter.accept(selectedFile)) {
			String fileName = selectedFile.getName();
			fileName += ReportFileFilter.EXTENSION;
			selectedFile = new File(selectedFile.getParent(), fileName);
		}
		return writeReport(selectedFile);
	}
	
	/**
	 * Write review to file and shows error message if fails
	 * @param f write to this file
	 * @return <code>true</code> if no errors occurred, 
	 * otherwise <code>false</code>
	 */
	private boolean writeReport(File f) {
		try {
			getPluginAdapter().getFileHistory().add(f, FILE_HISTORY_TYPE);
			ReportWriter writer = new XMLReportWriter();
			writer.write(getReport(), f);
			reportFile = f;
			getPluginAdapter().setTitle(reportFile.getName(), 
					reportFile.getAbsolutePath());
			getPluginAdapter().setFile(reportFile);
			return true;
		} catch(Throwable e) {
			getPluginAdapter().getSpringGlassPane().setFaded(true);
			JOptionPane.showMessageDialog(getComponent(), 
						e.getLocalizedMessage(), 
						Messages.getString("PearReview.error"), 
						JOptionPane.ERROR_MESSAGE);
			getPluginAdapter().getSpringGlassPane().setFaded(false);
		}
		
		return false;
	}
	
	public void openReport() {
		final JFileChooser openDialog = new JFileChooser();
		openDialog.setMultiSelectionEnabled(false);
		
		openDialog.setFileFilter(new ReportFileFilter());
		
		getPluginAdapter().getSpringGlassPane().setFaded(true);
		int ret = openDialog.showOpenDialog(getComponent());
		getPluginAdapter().getSpringGlassPane().setFaded(false);
			 
		if (JFileChooser.APPROVE_OPTION != ret)
			return;
				 
		File f = openDialog.getSelectedFile();
				 
		if (f.isFile() && f.canRead()) {
			openReport(f);
		}
	}
	
	public void openReport(File file) {
		if(isStartMode()) {
			readReport(file);
		} else {
			ReviewerPlugin plugin = new ReviewerPlugin();
			plugin.openReportOnRun(file);
			getPluginAdapter().newPluginTab(plugin, true);
		}
	}
	
	public void setReport(Report report) {
		this.report = report;
		
		if(!isStartMode()) {
			if(clock == null) {
				clock = new ScribeClock();
				clock.setPlannedTime(-1);
			}

			if(informationPanel == null) {
				informationPanel = new InformationPanel(getPluginAdapter());
			}
			
			if(findingsPanel == null) {
				findingsPanel = new FindingsPanel(
						getPluginAdapter().getSpringGlassPane());
				findingsPanel.setClock(clock);
				
			}
			
			if(finalPanel == null) {
				finalPanel = new FinalPanel(
						getPluginAdapter().getSpringGlassPane());
				finalPanel.setClock(clock);
			}
			
			views = new ReviewerPanel[]{startPanel, informationPanel, 
					findingsPanel, finalPanel};
			
			stepTabs.setMaxSelectionIndex(-1);
		} else {
			stepTabs.setMaxSelectionIndex(0);
		}
		
		saveReportAction.setEnabled(!isStartMode());
		saveAsReviewAction.setEnabled(!isStartMode());
		
		for(ReviewerPanel panel: views) {
			panel.setReport(report);
			panel.setNextViewAction(nextViewAction);
			panel.setPreviousViewAction(previousViewAction);
		}
	}
	
	public boolean readReport(File file) {
		try {
			ReportReader reader = new XMLReportReader();
			Report report = reader.read(file);
			getPluginAdapter().getFileHistory().add(file, FILE_HISTORY_TYPE);
			reportFile = file;
			setReport(report);
			setNextView();
			getPluginAdapter().setTitle(reportFile.getName(), 
					reportFile.getAbsolutePath());
			getPluginAdapter().setFile(reportFile);
			return true;
		} catch(Throwable e) {
			getPluginAdapter().getSpringGlassPane().setFaded(true);
			JOptionPane.showMessageDialog(getComponent(), 
						e.getLocalizedMessage(), 
						Messages.getString("PearReview.error"), 
						JOptionPane.ERROR_MESSAGE);
			getPluginAdapter().getSpringGlassPane().setFaded(false);
		}
		
		return false;
	}
	
	public void newReport() {
		if(isStartMode()) {
			startClockByNextFindingsPanelVisit = true;
			setReport(new Report());
			setNextView();
			getPluginAdapter().setTitle(getLocalizedString("start.new_file"), 
					getLocalizedString("start.new_file"));
		} else {
			ReviewerPlugin plugin = new ReviewerPlugin();
			plugin.newReportOnRun();
			getPluginAdapter().newPluginTab(plugin, true);
		}
	}
	
	private class TabListener implements ListSelectionListener, Serializable {
		private static final long serialVersionUID = 3812320855893054074L;
		@Override
		public void valueChanged(ListSelectionEvent e) {
			updateView();
		}
	}
	
	private class NextViewAction extends AbstractAction {
		private static final long serialVersionUID = -5051186228771979304L;
		@Override
		public void actionPerformed(ActionEvent e) {
			setNextView();
		}
	}
	
	private class PreviousViewAction extends AbstractAction {
		private static final long serialVersionUID = -5252028168971002171L;
		@Override
		public void actionPerformed(ActionEvent e) {
			setPreviousView();
		}
	}
	
	private class FirstViewAction extends AbstractAction {
		private static final long serialVersionUID = -6038555634600549846L;
		@Override
		public void actionPerformed(ActionEvent e) {
			setView(0);
		}
	}
	
	private class NewReportAction extends AbstractAction {
		private static final long serialVersionUID = -9080449949248315861L;
		public NewReportAction() {
			putValue(Action.NAME, getLocalizedString("menu.new"));
			
			putValue(Action.SMALL_ICON, getResourceIcon("new_16.png"));
			
			KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_N, 
					Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
			putValue(Action.ACCELERATOR_KEY, ks);
		}
		@Override
		public void actionPerformed(ActionEvent e) {
			newReport();
		}		
	}
	
	private class OpenReportAction extends AbstractAction {
		private static final long serialVersionUID = -6345476406073212774L;
		public OpenReportAction() {
			putValue(Action.NAME, getLocalizedString("menu.open"));
			
			KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_O, 
					Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
			putValue(Action.ACCELERATOR_KEY, ks);
		}
		@Override
		public void actionPerformed(ActionEvent e) {
			openReport();
		}
	}
	
	private class OpenReportFileAction extends AbstractAction {
		private static final long serialVersionUID = -9113610819924886299L;
		@Override
		public void actionPerformed(ActionEvent e) {
			openReport(startPanel.getHistoryFile());
		}
	}
	
	private class SaveReportAction extends AbstractAction {
		private static final long serialVersionUID = -6895080742593347857L;
		public SaveReportAction() {
			setEnabled(false);
			
			putValue(Action.SMALL_ICON, getResourceIcon("save_16.png"));
			
			putValue(Action.NAME, getLocalizedString("menu.save"));
			
			KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_S, 
					Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
			putValue(Action.ACCELERATOR_KEY, ks);
		}
		@Override
		public void actionPerformed(ActionEvent e) {
			saveReport();
		}		
	}
	
	private class SaveAsReportAction extends AbstractAction {
		private static final long serialVersionUID = -8493350029946035608L;
		public SaveAsReportAction() {
			setEnabled(false);
			
			putValue(Action.NAME, getLocalizedString("menu.save_as"));
		}
		@Override
		public void actionPerformed(ActionEvent e) {
			saveAsReport();
		}
	}
	
	private class NavigateToHomeAction extends AbstractAction {
		private static final long serialVersionUID = -197253003089209064L;
		public NavigateToHomeAction() {
			putValue(Action.SMALL_ICON, getResourceIcon("home_16.png"));
			
			putValue(Action.NAME, getLocalizedString("menu.home"));
		}
		@Override
		public void actionPerformed(ActionEvent e) {
			if(close()) {
				getPluginAdapter().navigateToStartTab();
			}
		}
	}
	
	private class NewTabAction extends AbstractAction {
		private static final long serialVersionUID = 8470209028426551267L;
		@Override
		public void actionPerformed(ActionEvent e) {
			getPluginAdapter().newStartTab(true);
		}
	}
	
	private class FullScreenAction extends AbstractAction {
		private static final long serialVersionUID = 5639674325866168103L;
		@Override
		public void actionPerformed(ActionEvent e) {
			getPluginAdapter().setFullScreen(
					!getPluginAdapter().isFullScreen());
		}
	}
}
